`ifndef RESET_MONITOR__SV
	`define RESET_MONITOR__SV
	
	typedef class reset_trans;
	typedef class reset_monitor;

	class reset_monitor extends uvm_monitor;
		uvm_analysis_port #(reset_trans) mon_analysis_port;  //TLM analysis port
		typedef virtual wb_master_if v_if;
		v_if mon_if;
		extern function new(string name = "reset_monitor",uvm_component parent);
		`uvm_component_utils(reset_monitor)

		extern virtual function void end_of_elaboration_phase(uvm_phase phase);
		extern virtual function void connect_phase(uvm_phase phase);
		extern virtual task run_phase(uvm_phase phase);
		extern protected virtual task monitor();
		// Reset Event
		uvm_event_pool my_event_pool;  // This will become global pool
		uvm_event      reset_event ;  // Reset Event to be used with global pool   
	endclass: reset_monitor


	function reset_monitor::new(string name = "reset_monitor",uvm_component parent);
		super.new(name, parent);
		mon_analysis_port = new ("mon_analysis_port",this);
		my_event_pool = uvm_event_pool::get_global_pool();
		reset_event = my_event_pool.get("reset_event");
	endfunction: new

	function void reset_monitor::connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		uvm_config_db#(v_if)::get(this, "", "mon_if", mon_if);
	endfunction: connect_phase

	function void reset_monitor::end_of_elaboration_phase(uvm_phase phase);
		super.end_of_elaboration_phase(phase); 
		if (mon_if == null)
			`uvm_fatal("NO_CONN", "Virtual port not connected to the actual interface instance");
	endfunction: end_of_elaboration_phase

	task reset_monitor::run_phase(uvm_phase phase);
		super.run_phase(phase);
		fork
			monitor();
		join_none

	endtask: run_phase


	task reset_monitor::monitor();
		/* This is left as an exercise for the reader to improve upon.
		 *  Only a rudimentary implementation is provided 
		 * See the assignments for what to fill in here
		 */
		forever begin
			@(mon_if.RST_O);
			assert(!$isunknown(mon_if.RST_O));
			if (mon_if.RST_O == 1'b1) begin
				reset_event.trigger();
			end else begin
				reset_event.reset();
			end
		end

      
	endtask: monitor

`endif // RESET_MONITOR__SV
